package com.ailk.cuc.autotestbg.xml.business.impl.ecs;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.Node;

import com.ailk.cuc.autotestbg.common.business.interf.ReplaceComponentInterface;
import com.ailk.cuc.autotestbg.xml.bean.AutoEssDataBean;
import com.ailk.cuc.autotestbg.xml.constants.EssEcsConstants;
import com.ailk.cuc.autotestbg.xml.exception.EcsReplaceException;

public class EcsReplaceComponentImpl implements ReplaceComponentInterface {
	
	private static Log logger = LogFactory.getLog(EcsReplaceComponentImpl.class);
	
	private AutoEssDataBean essDataBean;
	private Document essDoc = null;
	private Map<String, Object> mapIn;
	
	@SuppressWarnings("unchecked")
	public void replaceInfo(Map<String, Object> argMapIn,Map<String,Object> argMapOut) throws EcsReplaceException {
		// TODO Auto-generated method stub
		essDataBean = (AutoEssDataBean)argMapIn.get("ecsDataBean");
		long interfaceId = essDataBean.getInterfaceId();
		mapIn = argMapIn;
		logger.info("开始进行报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		
		String rulePath = (String)argMapIn.get(EssEcsConstants.XML_ESS_RULE_PATH);	
		if(rulePath == null|| rulePath.trim().equals("")){
			logger.info("没有规则文件，不必替换！");
			return;
		}
		logger.debug("规则文件路径："+rulePath);
		File ruleFile = new File(rulePath);
		String replaceRule = null;
		try {
			replaceRule = FileUtils.readFileToString(ruleFile);
			logger.debug("规则文件："+replaceRule);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new EcsReplaceException();

		}
		String interfaceIdStr = new Long(interfaceId).toString();
		int index = replaceRule.indexOf(interfaceIdStr);
		String deccRule = replaceRule.substring(index, index+18);
		
		if(deccRule.contains("rule")){						
			//要替换的xml
			String essMessageXml = (String)argMapIn.get(essDataBean.getInterfaceId()+"_request_"+"ecsMessageXml");	
			logger.debug("替换前报文："+essMessageXml);
			
			try {
				essDoc = DocumentHelper.parseText(essMessageXml);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EcsReplaceException();
			}
			Element essEle = essDoc.getRootElement();
			
			
			int beginIndex = replaceRule.indexOf("EOT", index);
			int endIndex = replaceRule.indexOf("EOT", beginIndex+3);
			String subRule = replaceRule.substring(beginIndex+4, endIndex).trim();
			logger.debug("本次替换规则序列："+subRule);
			StringBuffer subRuleBuffer = new StringBuffer(subRule);
			
			List<Namespace> nsList = essEle.declaredNamespaces();
			if(nsList!=null){
				Iterator<Namespace> nsIt = nsList.iterator();
				StringBuffer nsBuffer = new StringBuffer();
				while(nsIt.hasNext()){
					Namespace ns = nsIt.next();
					nsBuffer.append(" xmlns:").append(ns.getPrefix()).append("=\"").append(ns.getURI()).append("\"");
				}
				
				int beginInsert = subRuleBuffer.indexOf("<");
				int endInsert = subRuleBuffer.indexOf(">",beginInsert);
				
				subRuleBuffer = subRuleBuffer.insert(endInsert, nsBuffer);
				logger.debug("本次替换规则序列Namespace："+subRuleBuffer.toString());
			}
			
			//替换规则生成xml格式Docuement
			Document ruleDoc = null;
			try {
				ruleDoc = DocumentHelper.parseText(subRuleBuffer.toString());
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EcsReplaceException();
			}
			Element ruleEle = ruleDoc.getRootElement();
			
			relpaceContent(ruleEle,essEle);

			logger.debug("替换后报文："+essDoc.asXML());
			
			argMapIn.put(essDataBean.getInterfaceId()+"_request_"+"ecsMessageXml",essDoc.asXML());
			
			logger.info("完成报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		}else{
			logger.info("不需要进行报文替换dataId:"+essDataBean.getDataId()+",interfaceId:"+interfaceId);
		}

	}
	/*
	 * 遍历替换规则
	 * */
	@SuppressWarnings("unchecked")
	private void relpaceContent(Element ruleElement,Element essElement) throws EcsReplaceException{
		try {
			String lyytype = ruleElement.attributeValue("lyytype");
			if(lyytype==null||lyytype.equals("")){
				logger.info("非根节点："+ruleElement.getName());
				Iterator<Element> it = ruleElement.elementIterator();
				while(it.hasNext()){
					Element subRuleEle = it.next();
					relpaceContent(subRuleEle,essElement);
				}
			}else{
				if(lyytype.equals("ARRAY")){
					arrayXml(ruleElement);
				}else if(lyytype.equals("XML")){
					replaceXml(ruleElement);
				}else if(lyytype.equals("DELETE")){
					deleteXml(ruleElement);
				}else if(lyytype.equals("VALUE")){
					valueXml(ruleElement);
				}else if(lyytype.equals("SQL")){
					
				}else{
					logger.error("不存在lyytype为："+lyytype);
					throw new EcsReplaceException();
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new EcsReplaceException();
		}
	}
	/*
	 * xml替换
	 * */
	@SuppressWarnings("unchecked")
	private void replaceXml(Element ruleEleXml) throws EcsReplaceException{
		logger.info("XML替换"+ruleEleXml.getName());
		String source = ruleEleXml.getTextTrim();
		String[] sourceArray = source.split("\\.");
		String essXpath = ruleEleXml.getPath();
		Node essNode = essDoc.selectSingleNode(essXpath);

		String essRspReq = "_request_";
		if(sourceArray.length>2&&sourceArray[2].endsWith("RSP")){
			essRspReq = "_response_";
		}
		String essSourceMessageXml = (String)mapIn.get(sourceArray[0]+essRspReq+"ecsMessageXml");

		if(essSourceMessageXml == null||essSourceMessageXml.trim().equals("")){
			logger.error("源报文为空！");
			return;
		}
		Document sourceDoc = null;
		try {
			sourceDoc = DocumentHelper.parseText(essSourceMessageXml);
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new EcsReplaceException();
		}
		if(sourceDoc == null){
			logger.error("源报文不是XML！");
			return;
		}
		if(sourceArray.length>2){
			Element souEle = sourceDoc.getRootElement();
			Element bodyEle = souEle.element("Body");
			List<Element> uniEleList = bodyEle.elements();
			Element uniBodyEle = uniEleList.get(0).element(sourceArray[1]);
			for(int i=2;i<sourceArray.length;i++){
				if(uniBodyEle != null){
					uniBodyEle = uniBodyEle.element(sourceArray[i]);
				}else{
					break;
				}
			}
			if(uniBodyEle != null){
				essNode.setText(uniBodyEle.getText());
				logger.info(uniBodyEle.getName()+"替换"+essNode.getText());
			}
		}

	}
	/*
	 * 删除xml
	 * */
	private void deleteXml(Element ruleEleDele){
		logger.info("DELETE替换："+ruleEleDele.getName());
		String essXpath = ruleEleDele.getPath();
		logger.debug("DELETE:"+essXpath);
		Node delNode = essDoc.selectSingleNode(essXpath);
		essDoc.remove(delNode.detach());
		logger.info("删除"+delNode.getName());
	}
	/*
	 * 从规则文件取值
	 * */
	private void valueXml(Element ruleEleValue){
		logger.info("VALUE替换："+ruleEleValue.getName());
		String value = ruleEleValue.getText();
		String essXpath = ruleEleValue.getPath();
		logger.debug("VALUE:"+essXpath);
		Node valueNode = essDoc.selectSingleNode(essXpath);
		valueNode.setText(value);
		logger.debug(valueNode.getName()+"赋值"+value);
	}
	/*
	 * array替换
	 * */
	@SuppressWarnings("unchecked")
	private void arrayXml(Element ruleEleArray) throws EcsReplaceException{
		logger.info("ARRAY替换："+ruleEleArray.getName());
		String lyysrc = ruleEleArray.attributeValue("lyysrc");
		String[] lyysrcAraay = null;
		String essSourceMessageXml = null;
		Document sourceDoc = null;
		String sourceXpath = "/";
		
		Element souEle = null;
		Element bodyEle = null;
		List<Element> uniEleList = null;
		Element uniBodyEle = null;
		
		if(lyysrc!=null&&!lyysrc.equals("")){
			logger.debug("ARRAY.lyysrc:"+lyysrc);
			lyysrcAraay = lyysrc.split("\\.");
			String essRspReq = "_request_";
			if(lyysrcAraay.length>2&&lyysrcAraay[2].endsWith("RSP")){
				essRspReq = "_response_";
			}
			essSourceMessageXml = (String)mapIn.get(lyysrcAraay[0]+essRspReq+"ecsMessageXml");

			try {
				sourceDoc = DocumentHelper.parseText(essSourceMessageXml);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new EcsReplaceException();
			}
			souEle = sourceDoc.getRootElement();
			bodyEle = souEle.element("Body");
			uniEleList = bodyEle.elements();
			uniBodyEle = uniEleList.get(0).element(lyysrcAraay[1]);
			if(lyysrcAraay.length>2){
				for(int i=2;i<lyysrcAraay.length;i++){
					if(uniBodyEle != null){
						uniBodyEle = uniBodyEle.element(lyysrcAraay[i]);
					}else{
						break;
					}
				}		
			}
		}
		
		String lyymax = ruleEleArray.attributeValue("lyymax");
		int max = Integer.parseInt(lyymax);
		
		String essXpath1 = ruleEleArray.getPath();
		Element essElement = (Element)essDoc.selectSingleNode(essXpath1);
		Element essClone = (Element)essElement.clone();
		
		Element essParEle = essElement.getParent();
		essParEle.remove(essElement);
		for(int i=0;i<max;i++){
			essParEle.add((Element)essClone.clone());
		}
		
		Iterator<Element> arrIt = ruleEleArray.elementIterator();
		while(arrIt.hasNext()){
			Element subArrEle = arrIt.next();
			String essXpath = subArrEle.getPath();
			List<Node> essNodeList = essDoc.selectNodes(essXpath);
			String subLyyType = subArrEle.attributeValue("lyytype");
			logger.debug("节点类型："+subLyyType);
			if(subLyyType!=null&&!subLyyType.equals("")){
				if(subLyyType.equals("ARRAY")){
					arrayXml(subArrEle);
				}else if(subLyyType.equals("ARRAYVALUE")){
					logger.info("ARRAYVALUE:"+subArrEle.getName());
					String text = subArrEle.getText();
					logger.debug("所有数据："+text);
					String[] textArr = text.split(",");
					logger.debug(textArr.length+":"+textArr[0]+":"+textArr[1]);
					String splitStr = textArr[0];
					if(splitStr.equals("|")){
						splitStr = "\\|";
					}
					String[] data = textArr[1].split(splitStr);
					logger.debug(data.length+":"+data[0]+":"+data[1]+":"+data[2]);
					if(data.length!=max){
						logger.error("规则文件配置有误！lyymax与数据条数不一致！");
						throw new EcsReplaceException();
					}else if(essNodeList.size()!=max){
						logger.error("要替换的报文节点条数与lyymax数据条数不一致！");
						throw new EcsReplaceException();
					}
					for(int i=0;i<max;i++){
						essNodeList.get(i).setText(data[i]);
						logger.info(essNodeList.get(i).getName()+"赋值"+data[i]);
					}
				}
			}else{
				if(sourceDoc != null&&uniBodyEle != null){
					logger.info("ARRAY:"+subArrEle.getName());
					String lyyname = subArrEle.attributeValue("lyyname");
					logger.debug("替换节点："+sourceXpath+lyyname);
					List<Element> sourceElementList = uniBodyEle.elements(lyyname);
					if(sourceElementList.size()!=essNodeList.size()){
						logger.error("要替换的报文节点条数与源数据报文节点条数不一致！");
						throw new EcsReplaceException();
					}else if(essNodeList.size()!=max){
						logger.error("规则文件配置有误！lyymax与数据条数不一致！");
						throw new EcsReplaceException();
					}
					for(int i=0;i<max;i++){
						Node deNode = essNodeList.get(i);
						Node souNode = sourceElementList.get(i);
						deNode.setText(souNode.getText());
						logger.info(deNode.getName()+"赋值"+souNode.getText());
					}
				}
			}
		}
	}
}
